//command.c
#include "threadPool.h"
#include "command.h"
#include <shadow.h>
#include <unistd.h>
#include <crypt.h>
#include "head.h"
void initUser(user_t* user,char* username, char* passwd){
    bzero(user,sizeof(user_t));
    user->curWorkDir = (stack*)malloc(sizeof(stack));
    user->tmpStack = (stack*)malloc(sizeof(stack));
    sprintf(user->username,"%s",username);
    sprintf(user->passwd,"%s",passwd);
    myCd("",user);
}
int myLogin(int netfd,user_t* user){
    train_state_t* train = (train_t*)malloc(sizeof(train_t));
    sprintf(train->buff,"%s","please input username and passwa");
    train->length = strlen(train->buff);
    train->state = LOGIN;
    //将登录提示发给客户端
    send(netfd,train,sizeof(int)+sizeof(int)+train->length,0);
    //接收用户名和密码
    char username[128] = {0};
    char passwd[128] = {0};
    char salt[128] = {0};     //颜值
    char encry[128] = {0};
    //recv(netfd,train,sizeof(train_t),MSG_WAITALL);
    recv(netfd,&train->state,sizeof(int),MSG_WAITALL);
    recv(netfd,&train->length,sizeof(int),MSG_WAITALL);
    recv(netfd,train->buff,train->length,MSG_WAITALL);
    sprintf(username,"%s",train->buff);
    username[train->length] = '\0';
    recv(netfd,&train->state,sizeof(int),MSG_WAITALL);   
    recv(netfd,&train->length,sizeof(int),MSG_WAITALL);
    recv(netfd,&train->buff,train->length,MSG_WAITALL);
    sprintf(passwd,"%s",train->buff);
    passwd[train->length] = '\0';
    free(train);
    puts(username);
    puts(passwd);
    //判断用户名和密码是否一致
    struct spwd* sp;  //密文
    sp = getspnam(username);
    if(sp == NULL){
        printf("参数错误或用户名密码不正确\n");
        return 0;
    }
    sprintf(encry,"%s",sp->sp_pwdp);
    
    //提取颜值
    int len = strlen(encry);
    for(int i = 0, j = 0; i < len  && j != 3; i++){
        if(encry[i] == '$'){
            j++;
        }
        salt[i] = encry[i];
    }
    char* encryPasswd = crypt(passwd,salt);
    if(strcmp(encryPasswd,encry) == 0){
        printf("login success\n");
        //创建用户
        initUser(user,username,passwd);        
        return 1;
    }else{
        printf("root? or passwd or username is incrette\n");
        return 0;
    }
}

int myCd(char* arg,user_t* user){
    char fname[25];
    char tmp[25];
    char path[256] = "netDisk";
    char* p = strtok(arg,"/");
    int flag = 1;
    if(isEmpty(user->curWorkDir)){
        flag = 0;   //表示第一次cd
    }
    while(p != NULL){
        //printf("%s\n",p);
        if(strcmp(p,"..") == 0){ //等于.. ,弹栈
            Pop(user->curWorkDir,tmp);
        }else if(strcmp(p,".") == 0){

        }
        else{//具体的某个路径，压栈
            Push(user->curWorkDir,p);
        }
        p = strtok(NULL,"/");

    }

    //判断是否合法，合法就添加进path,不合法就全部弹栈.
    node_t* head = user->curWorkDir->top;
    while(head != NULL){
        Push(user->tmpStack,head->fname);
        head = head->next;
    }
    head = user->tmpStack->top;
    
    sprintf(path,"%s",user->username);
    sprintf(path,"%s/%s",path,"netDisk");
    while(head != NULL){
        sprintf(path,"%s/%s",path,head->fname);
        //printf("%s\n",path); 
        head = head->next;
    }
    
    int exite = access(path,F_OK);
    if(exite == 0){
        printf("Valid\n");
        head = user->tmpStack->top;
        memset(user->path,0,sizeof(user->path));
        sprintf(user->path,"%s",user->username);
        sprintf(user->path,"%s/%s",user->path,"netDisk");
        while(head != NULL){
            sprintf(user->path,"%s/%s",user->path,head->fname);
            head = head->next;
        }
        //printf("the path: %s\n",user->path);
    }else{//全部弹栈
        printf("Invalid\n");
        while(!isEmpty(user->curWorkDir)){
            Pop(user->curWorkDir,fname);
        }
        if(flag == 1){//不合法,所以需要将path中的路径全部押入到栈中,恢复当前目录
            p = strtok(user->path,"/");
            while(p != NULL){
                Push(user->curWorkDir,p);
                p = strtok(NULL," ");
            }
        }
    }
    //处理辅助栈
    head = user->tmpStack->top;
    while(!isEmpty(user->tmpStack)){
        Pop(user->tmpStack,fname);
    }
    return 0;
}
int myPwd(char* pwd,user_t* user){
    strcpy(pwd,user->path);
    return 0;
}


//入栈
int Push(stack* curWorkDir,char* fname){
    node_t* pnew = (node_t*)malloc(sizeof(node_t));
    int len = strlen(fname);
    for(int i = 0; i < len; i++){
        pnew->fname[i] = *fname;
        fname++;
    }
    pnew->fname[len] = '\0';
    pnew->next = NULL;

    if(curWorkDir->top == NULL){
        curWorkDir->top  = pnew;
        //curWorkDir->head = pnew;
    }else{
        pnew->next = curWorkDir->top;
        curWorkDir->top = pnew;
    }
    //printf("%s\n",curWorkDir->top->fname);
    curWorkDir->stackSize++;
    return 0;
}
//出栈
int Pop(stack* curWorkDir, char* fname){
    if(isEmpty(curWorkDir)){
        printf("stack is empty\n");
        return -1;
    }
    int len = strlen(curWorkDir->top->fname);
    for(int i = 0; i < len; i++){
        *fname = curWorkDir->top->fname[i];
        fname++;
    }
    *fname = '\0';

    node_t* pre = curWorkDir->top;
    curWorkDir->top = curWorkDir->top->next;

    free(pre);
    curWorkDir->stackSize--;
    if(curWorkDir->stackSize == 0){
        //curWorkDir->head = NULL;
    }
    return 0;
}

//查看栈顶
int Peek(stack* curWorkDir, char* fname){
    if(isEmpty(curWorkDir)){
        printf("stack is empty\n");
        return -1;
    }
    int len = strlen(curWorkDir->top->fname);
    for(int i = 0; i < len; i++){
        *fname = curWorkDir->top->fname[i];
        fname++;
    }
    *fname = '\0';
    return 0;
}
//判空
int isEmpty(stack* curWorkDir){
    return curWorkDir->stackSize == 0;
}

void print_stack(stack* curWorkDir){
    node_t* head = curWorkDir->top;
    while(head){
        printf("%s ",head->fname);
        head = head->next;
    }
}
